package com.ly.heart.service.impl;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ly.common.core.domain.AjaxResult;
import com.ly.common.core.domain.entity.SysDept;
import com.ly.common.exception.CustomException;
import com.ly.common.utils.DateUtils;
import com.ly.common.utils.SecurityUtils;
import com.ly.common.utils.StringUtils;
import com.ly.common.utils.erp.ConstUtil;
import com.ly.common.utils.erp.SnowflakeIdWorker;
import com.ly.heart.domain.AssetsChangeEntity;
import com.ly.heart.domain.AssetsDistributionEntity;
import com.ly.heart.domain.AssetsPhysicalEntity;
import com.ly.heart.domain.dto.StartProcessDto;
import com.ly.heart.mapper.AssetsMapper;
import com.ly.heart.service.*;
import com.ly.heart.util.ChineseToPinyin;
import com.ly.heart.util.CurrentUserUtil;
import com.ly.system.service.ISysDeptService;
import org.springframework.stereotype.Service;
import com.ly.heart.domain.AssetsEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;

/**
 * 资产卡片Service业务层处理
 *
 * @author cxl
 * @date 2024-09-03
 */
@Service
public class AssetsServiceImpl extends ServiceImpl<AssetsMapper,AssetsEntity> implements IAssetsService {

    @Resource
    private AssetsMapper assetsMapper;
    @Resource
    private ISysDeptService sysDeptService;
    @Resource
    private IAssetsPhysicalService assetsPhysicalService;
    @Resource
    private IAssetsDistributionService assetsDistributionService;
    @Resource
    private IActModelService actModelService;
    @Resource
    private IAssetsChangeService assetsChangeService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult draft(AssetsEntity assetsEntity){
        if(StringUtils.isEmpty(assetsEntity.getId())){
            String assetsId = SnowflakeIdWorker.getInstance().nextStringId();
            Date nowDate = DateUtils.getNowDate();
            String userId = SecurityUtils.getLoginUser().getUser().getUserId();
            assetsEntity.setId(assetsId).setCreateBy(userId).setCreateDept(CurrentUserUtil.getDeptId()).setCreateTime(nowDate);
            //生成资产卡片编码
            if(StringUtils.isEmpty(assetsEntity.getDocCode())){
                String companyId = CurrentUserUtil.getCompanyId();
                SysDept sysDept = sysDeptService.getById(companyId);
                Integer count = assetsMapper.queryCount();
                String countStr = String.format("%06d", count + 1);
                String firstLetter = ChineseToPinyin.getFirstLetter(sysDept.getDeptName());
                String docCode = firstLetter.concat("_ZCKP_").concat(countStr);
                assetsEntity.setDocCode(docCode);
            }
            //保存资产实物信息
            if(!CollectionUtils.isEmpty(assetsEntity.getPhysicalList())){
                saveAssetsPhysical(assetsEntity);
            }
            //保存资产分配信息
            if(!CollectionUtils.isEmpty(assetsEntity.getDistributionList())){
                saveAssetsDistribution(assetsEntity);
            }
            //流程状态：暂存
            assetsEntity.setState(ConstUtil.STATE_IN_DRAFT);
            boolean save = this.save(assetsEntity);
            if(!save){
                throw new CustomException("暂存资产卡片失败！");
            }
            return AjaxResult.success("暂存资产卡片成功！",assetsEntity.getId());
        }else{
            return update(assetsEntity);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult submit(AssetsEntity assetsEntity) {
        if ( StringUtils.isEmpty ( assetsEntity.getId () ) ) {
            return AjaxResult.error ("请先暂存该单据！");
        }
        if(Objects.isNull(assetsEntity.getModelId())){
            return AjaxResult.error("审批流程modelId不能为空！");
        }
        //先删除资产卡片实物信息和分配信息
        removeAssetsPhysicalAndDistribution(assetsEntity.getId());
        //保存资产卡片实物信息
        saveAssetsPhysical(assetsEntity);
        //保存分配信息
        saveAssetsDistribution(assetsEntity);
        //启动审批流程
        StartProcessDto startDto = new StartProcessDto().setBusinessId(assetsEntity.getId()).setBusinessType(assetsEntity.getBusinessType()).setModelId(assetsEntity.getModelId());
        startDto.setBusinessName("资产卡片_".concat(assetsEntity.getCardCode()));
        String instanceId = actModelService.startProcess(startDto);
        assetsEntity.setState(ConstUtil.STATE_IN_PROCESS).setInstanceId(instanceId);
        boolean updated = this.updateById(assetsEntity);
        if ( !updated ) {
            return AjaxResult.error( "提交资产卡片失败！!" );
        }
        return AjaxResult.success ( "提交资产卡片成功!" );
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult update(AssetsEntity assetsEntity) {
        if ( StringUtils.isEmpty ( assetsEntity.getId () ) ) {
            return AjaxResult.error ("资产卡片id为空！");
        }
        //先删除资产卡片实物信息和分配信息
        removeAssetsPhysicalAndDistribution(assetsEntity.getId());
        //保存资产实物信息
        if(!CollectionUtils.isEmpty(assetsEntity.getPhysicalList())){
            saveAssetsPhysical(assetsEntity);
        }
        //保存资产分配信息
        if(!CollectionUtils.isEmpty(assetsEntity.getDistributionList())){
            saveAssetsDistribution(assetsEntity);
        }
        boolean updated = this.updateById(assetsEntity);
        if ( !updated ) {
            throw new CustomException("修改资产卡片失败！!");
        }
        return AjaxResult.success ( "修改资产卡片成功!",assetsEntity.getId());
    }

    /**
     * 资产卡片变更
     * 车牌号；资产唯一识别码；资产类别；开始使用日期；购进原值；预计净残值；预计使用期间
     * 上面任一字段发生变更即生成一条变更单
     * @param newAssets
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult change(AssetsEntity newAssets){
        if(StringUtils.isEmpty(newAssets.getId())){
            return AjaxResult.error("资产卡片id不能为空！");
        }
        AssetsEntity oldAssets = this.getById(newAssets.getId());
        //判断车牌号
        if(StringUtils.isNotEmpty(newAssets.getCarNum()) && !oldAssets.getCarNum().equals(newAssets.getCarNum())){
            assembleAssetsChange(newAssets,"车牌号",oldAssets.getCarNum(),newAssets.getCarNum());
        }
        //资产唯一识别码
        if(StringUtils.isNotEmpty(newAssets.getUniqueIdentifyCode()) && !oldAssets.getUniqueIdentifyCode().equals(newAssets.getUniqueIdentifyCode())){
            assembleAssetsChange(newAssets,"资产唯一识别码",oldAssets.getUniqueIdentifyCode(),newAssets.getUniqueIdentifyCode());
        }
        //资产类别
        if(StringUtils.isNotEmpty(newAssets.getAssetsTypeId()) && !oldAssets.getAssetsTypeId().equals(newAssets.getAssetsTypeId())){
            assembleAssetsChange(newAssets,"资产类别",oldAssets.getAssetsTypeId(),newAssets.getAssetsTypeId());
        }
        //开始使用日期
        if(Objects.nonNull(newAssets.getUseStartTime()) && !oldAssets.getUseStartTime().equals(newAssets.getUseStartTime())){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String oldData = sdf.format(oldAssets.getUseStartTime());
            String newData = sdf.format(newAssets.getUseStartTime());
            assembleAssetsChange(newAssets,"开始使用日期",oldData,newData);
        }
        //购进原值
        if(Objects.nonNull(newAssets.getBuyValue()) && !oldAssets.getBuyValue().equals(newAssets.getBuyValue())){
            assembleAssetsChange(newAssets,"购进原值",oldAssets.getBuyValue(),newAssets.getBuyValue());
        }
        //预计净残值
        if(Objects.nonNull(newAssets.getExpectedResidualValue()) && !oldAssets.getExpectedResidualValue().equals(newAssets.getExpectedResidualValue())){
            assembleAssetsChange(newAssets,"预计残值",oldAssets.getExpectedResidualValue(),newAssets.getExpectedResidualValue());
        }
        //预计使用期间
        if(Objects.nonNull(newAssets.getExpectedUsePeriod()) && !oldAssets.getExpectedUsePeriod().equals(newAssets.getExpectedUsePeriod())){
            assembleAssetsChange(newAssets,"预计使用期间",oldAssets.getExpectedUsePeriod(),newAssets.getExpectedUsePeriod());
        }
        //先删除资产卡片实物信息和分配信息
        removeAssetsPhysicalAndDistribution(newAssets.getId());
        //保存资产实物信息
        if(!CollectionUtils.isEmpty(newAssets.getPhysicalList())){
            saveAssetsPhysical(newAssets);
        }
        //保存资产分配信息
        if(!CollectionUtils.isEmpty(newAssets.getDistributionList())){
            saveAssetsDistribution(newAssets);
        }
        newAssets.setUpdateBy(SecurityUtils.getLoginUser().getUser().getUserId());
        newAssets.setUpdateTime(DateUtils.getNowDate());
        boolean updated = this.updateById(newAssets);
        if(!updated){
            throw new CustomException("资产卡片变更失败！");
        }
        return AjaxResult.success("资产卡片变更成功！");
    }

    /**
     * 组装变更单内容
     * @param assetsEntity
     * @param changeData
     * @param oldValue
     * @param newValue
     */
    private void assembleAssetsChange(AssetsEntity assetsEntity,String changeData,String oldValue,String newValue){
        AssetsChangeEntity assetsChange = new AssetsChangeEntity();
        assetsChange.setId(SnowflakeIdWorker.getInstance().nextStringId());
        assetsChange.setAssetsId(assetsEntity.getId());
        assetsChange.setDocCode(assetsEntity.getDocCode());
        assetsChange.setCardCode(assetsEntity.getCardCode());
        assetsChange.setAssetsOrg(assetsEntity.getAssetsOrg());
        assetsChange.setCargoOwnerOrg(assetsEntity.getCargoOwnerOrg());
        assetsChange.setAssetsName(assetsEntity.getAssetsName());
        assetsChange.setChangeData(changeData);
        assetsChange.setBeforeChangeData(oldValue);
        assetsChange.setAfterChangeData(newValue);
        assetsChange.setCreateBy(SecurityUtils.getLoginUser().getUser().getUserId());
        assetsChange.setCreateTime(DateUtils.getNowDate());
        assetsChange.setCreateDept(assetsEntity.getCreateDept());
        boolean save = assetsChangeService.save(assetsChange);
        if(!save){
            throw new CustomException("新增资产卡片变更单失败！");
        }
    }

    /**
     * 保存资产卡片实物信息
     * @param assetsEntity
     */
    private void saveAssetsPhysical(AssetsEntity assetsEntity){
        List<AssetsPhysicalEntity> physicalList = assetsEntity.getPhysicalList();
        physicalList.forEach(assetsPhysical -> {
            assetsPhysical.setId(SnowflakeIdWorker.getInstance().nextStringId());
            assetsPhysical.setAssetsId(assetsEntity.getId());
            assetsPhysical.setCreateBy(assetsEntity.getCreateBy());
            assetsPhysical.setCreateTime(assetsEntity.getCreateTime());
        });
        boolean saveBatch = assetsPhysicalService.saveBatch(physicalList);
        if(!saveBatch){
            throw new CustomException("新增资产实物信息异常！");
        }
    }

    /**
     * 保存资产卡片分配信息
     * @param assetsEntity
     */
    private void saveAssetsDistribution(AssetsEntity assetsEntity){
        List<AssetsDistributionEntity> distributionList = assetsEntity.getDistributionList();
        distributionList.forEach(assetsDistribution -> {
            assetsDistribution.setId(SnowflakeIdWorker.getInstance().nextStringId());
            assetsDistribution.setAssetsId(assetsEntity.getId());
            assetsDistribution.setCreateBy(assetsEntity.getCreateBy());
            assetsDistribution.setCreateTime(assetsEntity.getCreateTime());
        });
        boolean saveBatch = assetsDistributionService.saveBatch(distributionList);
        if(!saveBatch){
            throw new CustomException("新增资产分配信息异常！");
        }
    }

    /**
     * 查询资产卡片
     * @param id 资产卡片ID
     * @return 资产卡片
     */
    @Override
    public AssetsEntity selectAssetsEntityById(String id)
    {
        AssetsEntity assetsEntity = assetsMapper.selectAssetsEntityById(id);
        if(Objects.nonNull(assetsEntity)){
            List<AssetsPhysicalEntity> physicalList = assetsPhysicalService.list(new LambdaQueryWrapper<AssetsPhysicalEntity>().eq(AssetsPhysicalEntity::getAssetsId, assetsEntity.getId()));
            assetsEntity.setPhysicalList(physicalList);
            List<AssetsDistributionEntity> distributionList = assetsDistributionService.list(new LambdaQueryWrapper<AssetsDistributionEntity>().eq(AssetsDistributionEntity::getAssetsId, assetsEntity.getId()));
            assetsEntity.setDistributionList(distributionList);
        }
        return assetsEntity;
    }

    /**
     * 查询资产卡片列表
     * @param assetsEntity 资产卡片
     * @return 资产卡片
     */
    @Override
    public List<AssetsEntity> selectAssetsEntityList(AssetsEntity assetsEntity)
    {
        return assetsMapper.selectAssetsEntityList(assetsEntity);
    }

    /**
     * 新增资产卡片
     * @param assetsEntity 资产卡片
     * @return 结果
     */
    @Override
    public int insertAssetsEntity(AssetsEntity assetsEntity)
    {
        assetsEntity.setCreateTime(DateUtils.getNowDate());
        return assetsMapper.insertAssetsEntity(assetsEntity);
    }

    /**
     * 修改资产卡片
     * @param assetsEntity 资产卡片
     * @return 结果
     */
    @Override
    public int updateAssetsEntity(AssetsEntity assetsEntity)
    {
        assetsEntity.setUpdateTime(DateUtils.getNowDate());
        return assetsMapper.updateAssetsEntity(assetsEntity);
    }

    /**
     * 批量删除资产卡片
     * @param ids 需要删除的资产卡片ID
     * @return 结果
     */
    @Override
    public int deleteAssetsEntityByIds(String[] ids)
    {
        for(String id : ids){
            removeAssetsPhysicalAndDistribution(id);
        }
        return assetsMapper.deleteAssetsEntityByIds(ids);
    }

    /**
     * 删除资产卡片信息
     * @param id 资产卡片ID
     * @return 结果
     */
    @Override
    public int deleteAssetsEntityById(String id)
    {
        removeAssetsPhysicalAndDistribution(id);
        return assetsMapper.deleteAssetsEntityById(id);
    }

    private void removeAssetsPhysicalAndDistribution(String id){
        assetsPhysicalService.remove(new LambdaQueryWrapper<AssetsPhysicalEntity>().eq(AssetsPhysicalEntity::getAssetsId,id));
        assetsDistributionService.remove(new LambdaQueryWrapper<AssetsDistributionEntity>().eq(AssetsDistributionEntity::getAssetsId,id));
    }


}
